package work.mediway.mdm.biz.service.biz.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mediway.hos.app.base.seure.util.SecurityUtils;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import work.mediway.mdm.core.page.QueryRequest;
import work.mediway.mdm.core.util.DUtil;
import work.mediway.mdm.biz.dto.biz.SsTablePermDTO;
import work.mediway.mdm.biz.mapper.biz.SsUserLinkTableMapper;
import work.mediway.mdm.biz.vo.biz.SsTablePermVO;
import work.mediway.mdm.biz.entity.biz.SsRoleLinkTable;
import work.mediway.mdm.biz.entity.biz.SsUserLinkTable;
import work.mediway.mdm.biz.service.biz.SsRoleLinkTableService;
import work.mediway.mdm.biz.service.biz.SsUserLinkTableService;

/**
 * @author zhongyj <1126834403@qq.com><br/>
 * @date 2021/3/25
 */
@Service
public class SsUserLinkTableServiceImpl extends ServiceImpl<SsUserLinkTableMapper, SsUserLinkTable> implements SsUserLinkTableService {

    @Resource
    private SsRoleLinkTableService roleLinkTableService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveTablePerm(List<SsUserLinkTable> userLinkTables) {
        // userLinkTables中可以同时包含绑定角色和绑定用户的数据
        List<Long> containLinkIds = userLinkTables.stream().filter(item -> ObjectUtil.isNotEmpty(item.getSsLinkId())).map(SsUserLinkTable::getSsLinkId).collect(Collectors.toList());
        List<SsRoleLinkTable> updateTableRoleData = CollUtil.newArrayList();
        List<SsUserLinkTable> updateTableUserData = CollUtil.newArrayList();
        List<SsRoleLinkTable> saveTableRoleData = CollUtil.newArrayList();
        List<SsUserLinkTable> saveTableUserData = CollUtil.newArrayList();
        List<SsUserLinkTable> notExistData = CollUtil.newArrayList();
        if (CollUtil.isNotEmpty(containLinkIds)) {
            // 查询linkId不为空的已存在数据
            List<SsRoleLinkTable> linkRoleTables = this.roleLinkTableService.listByIds(containLinkIds);
            Map<Long, SsRoleLinkTable> linkRoleTableMap = linkRoleTables.stream().collect(Collectors.toMap(SsRoleLinkTable::getSsLinkId, roleLinkTable -> roleLinkTable));
            List<SsUserLinkTable> linkUserTables = this.listByIds(containLinkIds);
            Map<Long, SsUserLinkTable> linkUserTableMap = linkUserTables.stream().collect(Collectors.toMap(SsUserLinkTable::getSsLinkId, userLinkTable -> userLinkTable));
            userLinkTables.forEach(item -> {
                if (ObjectUtil.isNotEmpty(linkRoleTableMap.get(item.getSsLinkId()))) {
                    SsRoleLinkTable ssRoleLinkTable = linkRoleTableMap.get(item.getSsLinkId());
                    BeanUtil.copyProperties(item, ssRoleLinkTable);
                    ssRoleLinkTable.setSsUpdateDate(DUtil.splitNow()[0]);
                    ssRoleLinkTable.setSsUpdateTime(DUtil.splitNow()[1]);
                    ssRoleLinkTable.setSsUpdateUser(SecurityUtils.getLoginName());
                    updateTableRoleData.add(ssRoleLinkTable);
                } else if (ObjectUtil.isNotEmpty(linkUserTableMap.get(item.getSsLinkId()))) {
                    SsUserLinkTable ssUserLinkTable = linkUserTableMap.get(item.getSsLinkId());
                    BeanUtil.copyProperties(item, ssUserLinkTable);
                    ssUserLinkTable.setSsUpdateDate(DUtil.splitNow()[0]);
                    ssUserLinkTable.setSsUpdateTime(DUtil.splitNow()[1]);
                    ssUserLinkTable.setSsUpdateUser(SecurityUtils.getLoginName());
                    updateTableUserData.add(ssUserLinkTable);
                } else {
                    notExistData.add(item);
                }
            });
            savePrem(updateTableRoleData, updateTableUserData, saveTableRoleData, saveTableUserData, notExistData);
        } else {
            savePrem(updateTableRoleData, updateTableUserData, saveTableRoleData, saveTableUserData, userLinkTables);
        }
    }

    private void savePrem(List<SsRoleLinkTable> updateTableRoleData, List<SsUserLinkTable> updateTableUserData, List<SsRoleLinkTable> saveTableRoleData, List<SsUserLinkTable> saveTableUserData, List<SsUserLinkTable> notExistData) {
        notExistData.forEach(item -> {
            item.setSsCreateDate(DUtil.splitNow()[0]);
            item.setSsCreateTime(DUtil.splitNow()[1]);
            item.setSsCreateUser(SecurityUtils.getLoginName());
            item.setSsUpdateDate(DUtil.splitNow()[0]);
            item.setSsUpdateTime(DUtil.splitNow()[1]);
            item.setSsUpdateUser(SecurityUtils.getLoginName());
            if (StrUtil.isNotBlank(item.getSsRole())) {
                // 绑定角色
                SsRoleLinkTable roleLinkTable = BeanUtil.copyProperties(item, SsRoleLinkTable.class);
                roleLinkTable.setSsRole(item.getSsRole());
                saveTableRoleData.add(roleLinkTable);
            }
            if (StrUtil.isNotBlank(item.getSsUser())) {
                // 绑定用户
                saveTableUserData.add(item);
            }
        });
        this.roleLinkTableService.updateBatchById(updateTableRoleData);
        this.updateBatchById(updateTableUserData);
        this.roleLinkTableService.saveOrUpdateBatch(saveTableRoleData);
        this.saveOrUpdateBatch(saveTableUserData);
    }

    @Override
    public Page<SsTablePermVO> pageTablePerm(SsTablePermDTO tablePermDTO, QueryRequest
            queryRequest) {
        // 解决XML中动态SQL为空
        if (StrUtil.isAllBlank(tablePermDTO.getUserId(), tablePermDTO.getRoleId(), tablePermDTO.getExtraSystemCode())) {
            tablePermDTO.setUserId("-1");
        }

        Page<SsTablePermVO> page = new Page<>(queryRequest.getCurrent(), queryRequest.getSize());
        page.setRecords(this.baseMapper.listTablePerm(page, tablePermDTO));

        for (SsTablePermVO record : page.getRecords()) {
            record.setSsUser(StrUtil.equals(tablePermDTO.getUserId(), "-1") ? "" : tablePermDTO.getUserId());
            record.setSsRole(tablePermDTO.getRoleId());
        }

        return page;
    }
}
